<?php
/**
 * Created by PhpStorm.
 * User: youZi
 * Date: 2017/7/13
 * Time: 10:05
 */

namespace Task\App\Healthscorebjhq;

use Task\App\Base\BuildBaseInfo;
use Task\Core\Base;
use Task\Core\RedisQueueService;
use Task\Core\RedisService;

class HealthScore extends Base
{
    public $mysql;
    public $accountId;

    public function __construct()
    {
        parent::__construct();
        $this->mysql = $this->selectDB('health_mysql');
        $this->accountId = $_SERVER['argv'][3];
    }

    /*
     * 持续更新项目管理，并加入对应的表中
     */
    public function updateItem()
    {
        //取项目表gc_health_item里面的数据,如果当前时间大于数据表里面的有效时间且status为0，则将edit字段覆盖正式字段
        $time = time();
        $sql1 = "select * from gc_health_item where status = 0 and valid_time < {$time}";//取出导入表里面的数据
        $data1 = $this->mysql->query($sql1)->fetchAll(\PDO::FETCH_ASSOC);
        if (count($data1) > 0) {
            foreach ($data1 as $key1 => $val1) {
                $sql = "update gc_health_item set pid = {$val1['edit_pid']},name = '{$val1['edit_name']}',score = {$val1['edit_score']},cut_off = {$val1['edit_off']},status = 1,create_time = $time where item_id = {$val1['item_id']}";
                //print_r($sql);die;
                $res = $this->mysql->exec($sql);
            }
        } else {
            echo date("Y-m-d", $time) . "：no item result\n";
        }
    }

    /*
     * 持续更新每个打分员的区域分配
     */
    public function updateAuth()
    {
        //取项目表gc_health_auth里面的数据,如果当前时间大于数据表里面的有效时间且status为0，则将edit字段覆盖正式字段
        $time = time();
        $sql = "select * from gc_health_auth where cut_off = 0 and status = 0 and valid_time < {$time}";//取出导入表里面的数据
        $data = $this->mysql->query($sql)->fetchAll(\PDO::FETCH_ASSOC);
        if (count($data) > 0) {
            foreach ($data as $key => $val) {
                //更新权限
                $sql = "update gc_health_auth set building_id = {$val['edit_building_id']},status = 1 where auth_id ={$val['auth_id']}";
                $res = $this->mysql->exec($sql);
                //error_log(date("Y-m-d H:i:s")."data:".$sql,3,"/tmp/youZi/auth.log");
            }
        } else {
            echo date("Y-m-d", $time) . "：no health auth result\n";
        }
    }
    /**********************************************以宿舍为单位生成任务记录表************************************************/
    /*
     * 定时给人生成任务记录表
     */
    public function createTask()
    {
        $time = time();
        //打分的执行周期记录表
        $sqlTimes = "select * from gc_health_times where cut_off = 0 order by create_time desc limit 1";
        $times = $this->mysql->query($sqlTimes)->fetch(\PDO::FETCH_ASSOC);
        //判断当前的任务是否在最近任务里面，如果是，就不执行下一个任务。
        //否则就创建任务
        if($times){
            $judge = explode('至',$times['start_end']);
            $min = strtotime($judge[0]);
            $max = strtotime($judge[1])+86400;
            if($time > $min && $time <= $max){
                echo date('Y-m-d H:i:s')."nothing done!\n";
                exit;
            }
        }

        $service = new BuildBaseInfo($this->accountId);
        /*$redisService = new RedisService();
        $serviceQueue = RedisQueueService::getInstance();*/
        //查看评分开始日，判断当前时间时候在开始日之后，周期之前才有效，否则没任务，另外任务跑了多少次，都需要记录到表gc_health_times表中
        $sqlSet = "select * from gc_health_set where account_id = {$this->accountId} and cut_off = 0 limit 1";
        $set = $this->mysql->query($sqlSet)->fetch(\PDO::FETCH_ASSOC);

        /*$end_times = $set[0]['start_time'] + ($times[0]['times']+1)*$set[0]['days']*86500;*/
        if($times){
            $start = $max+1;
        }else{
            $start = $set['start_time'];
        }
        $middle = date('Y-m-d',$start);
        $end = strtotime($middle) + 86400*$set['days']-1;
        $startEnd = date('Y-m-d', $start) . '至' . date('Y-m-d', $end);
        $cycle = $times['times'] ? $times['times'] + 1 : 1;//这是第几个周期

        if ($time <= $set['start_time']) {
            exit(date("Y-m-d", $time) . "：no  result");
        }

        //满足条件以后，先调用区域分配与项目更新操作
        $this->updateAuth();
        $this->updateItem();
        //获取所有的打分员
        $sqlUser = "select * from gc_health_auth where cut_off = 0";
        $user = $this->mysql->query($sqlUser)->fetchAll(\PDO::FETCH_ASSOC);
        $task = array();
        foreach ($user as $k => &$v) {
            $buildInfo = $service->getBuildInfo($v['building_id']);
            $v['floorList'] = $this->getData($v['building_id']);
            $v['community_id'] = $buildInfo['community_id'];
            $v['times'] = $set['times'];//设置的打分次数
            $v['cycle'] = $cycle;//这是第几个周期
            $v['start_end'] = $startEnd;
        }
        //数据节后结构是一个楼撞下面有楼层，楼层下面有宿舍的 三维数组,遍历生成任务记录；
        foreach ($user as $k0 => $v0) {
            if (!count($v0['floorList'])) {
                continue;
            }

            foreach ($v0['floorList'] as $k1 => $v1) {  //循环楼层列表
                if (!is_array($v1['roomList']) || !isset($v1['roomList']) ) {
                    continue;
                }

                foreach ($v1['roomList'] as $k2 => $v2) {
                    $task[] = array(
                        'community_id' => $v0['community_id'],
                        'building_id' => $v0['building_id'],
                        'floor_id' => $v1['floor_id'],
                        'room_id' => $v2['room_id'],
                        'health_user_id' => $v0['health_user_id'],
                        'times' => $v0['times'],
                        'cycle' => $v0['cycle'],
                        'create_time' => $time,
                        'cut_off' => 0, 'status' => 0,
                        'start_end' => $v0['start_end']
                    );
                }
            }
        }
        //将任务记录插入到mysql数据库中
        $res = $this->mysql->insert("health_task", $task);   //如果存在相同的数据就替换
        if (!$res) {
            wLog("failed to insert !\n", 'HealthScoreData');
            exit();
        } else {
            echo date('Y-m-d H:i:s')."add task data success \n";
        }

        $sqlTimes = "insert into gc_health_times (start_end,times,create_time,cut_off) values('{$startEnd}',$cycle, $time, 0)";
        $res = $this->mysql->exec($sqlTimes);
        if (!$res) {
            wLog("failed to insert with gc_health_times !\n", 'createTask');
            exit();
        } else {
            echo date('Y-m-d H:i:s')."add health_times data success \n";
        }
    }

    /****************************************************数据统计******************************************************/
    /*
     * 数据统计
     */
    public function dataCount()
    {
        $time = time();
        //取出评分级别
        $verifySql = "select * from gc_health_level where cut_off = 0";
        $verify = $this->mysql->query($verifySql)->fetchAll(\PDO::FETCH_ASSOC);
        //统计上一个周期各个数据统计;并且还要区分每个room_id是第几次打分用来算该周期内打分的平均值
        //取出上一个周期的打分时间段
        $lastSql = "select * from gc_health_times where cut_off = 0 order by times_id desc limit 2";
        $lastData = $this->mysql->query($lastSql)->fetchAll(\PDO::FETCH_ASSOC);
        //如果是第一周，就不参与统计
        if (count($lastData) <= 1) {
            echo "this is the first week,so do not statists!\n";
            return true;
        }
        $lastWeek = array_pop($lastData);

        $dataSql = "select start_end,sum(play_score) as score,room_id,times,status,start_end,create_time 
                    from gc_health_record where cut_off = 0 and start_end = '{$lastWeek['start_end']}' group by room_id,status 
                    order by record_id";
        $data = $this->mysql->query($dataSql)->fetchAll(\PDO::FETCH_ASSOC);

        if(count($data)>0){
            //评分等级看次任务提交了多少次，再算平均分,因为是按照record_id排序的，所以可以用后面的status覆盖前面的，来定位是第几次打分
            $test = array();
            foreach ($data as $k => $v) {
                $test[$v['room_id']]['room_id'] = $v['room_id'];
                $test[$v['room_id']]['start_end'] = $v['start_end'];
                $test[$v['room_id']]['status'] = $v['status'];
                $test[$v['room_id']]['times'] = $v['times'];
                $test[$v['room_id']]['create_time'] = $v['create_time'];
                $test[$v['room_id']]['score'] += $v['score'];
            }
            //统计每个周期的各种等级数量
            $healthCountArr = array();
            $totalNum = count($test);
            global $START_END;
            global $CREATE_TIME;
            foreach ($verify as $key => $value) {
                foreach ($test as $k => $v) {
                    if (ceil($v['score'] / $v['status']) > $value['min_score'] && ceil($v['score'] / $v['status']) <= $value['max_score']) {
                        $healthCountArr[$value['health_level_id']]['room_num'] += 1;
                        $healthCountArr[$value['health_level_id']]['health_level_id'] = $value['health_level_id'];
                        $healthCountArr[$value['health_level_id']]['start_end'] = $v['start_end'];
                        $START_END = $v['start_end'];
                        $healthCountArr[$value['health_level_id']]['create_time'] = $v['create_time'];
                        $CREATE_TIME = $v['create_time'];
                        $healthCountArr[$value['health_level_id']]['total_num'] = $totalNum;
                    }
                }
            }

            //如果不存在，当0处理
            foreach ($verify as $k=>$v){
                if(!array_key_exists($v['health_level_id'],$healthCountArr)){
                    $healthCountArr[$v['health_level_id']]['room_num'] = 0;
                    $healthCountArr[$v['health_level_id']]['health_level_id'] = $v['health_level_id'];
                    $healthCountArr[$v['health_level_id']]['start_end'] = $START_END;
                    $healthCountArr[$v['health_level_id']]['create_time'] = $CREATE_TIME;
                    $healthCountArr[$v['health_level_id']]['total_num'] = $totalNum;
                }
            }

            //此周期只统计上周期的数据
            $add = array();
            foreach ($healthCountArr as $K => $v){
                $add[] = $v;
            }
        }else{
            $add = array();
            foreach ($verify as $k=>$v){
                $add[] = array('start_end'=>$lastWeek['start_end'],
                    'room_num'=>0,
                    'health_level_id'=>$v['health_level_id'],
                    'total_num'=>0,
                    'create_time'=>0
                );
            }
        }

        //如果数据表中已经存在当前打分时间段的数据，则忽略

        $hasSql = "select * from gc_health_count where start_end = '{$add[0]['start_end']}'";
        $has = $this->mysql->query($hasSql)->fetch(\PDO::FETCH_ASSOC);
        if($has){
            echo date('Y-m-d H:i:s')."在同一周期里面已经统计过了，不用再统计\n";
            exit;
        }

        //将统计记录插入到mysql数据库中
        $res = $this->mysql->insert("health_count", $add);
        if (!$res) {
            wLog("failed to insert !\n", 'dataCount');
            exit();
        } else {
            echo date('Y-m-d H:i:s')."统计数据成功！";
        }
    }

    /*
     * 获取楼幢下面楼层下面的宿舍
     * $param $building int
     */
    private function getData($building)
    {
        $service = new BuildBaseInfo($this->accountId);
        $data = $service->getFloorListByBuildingId($building);
        if(is_array($data)){
            foreach ($data as $k => $v) {
                $data[$k]['roomList'] = $service->getRoomListByFloorId($v['floor_id']);
            }
        }
        return $data;
    }
}